﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Diagnostics;

namespace D20.Entities.Items
{
    /// <summary>
    /// Represents a collection of items.
    /// </summary>
    [Serializable]
    public class Inventory
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Inventory"/> class.
        /// </summary>
        public Inventory()
            : this(null)
        {

        }
        /// <summary>
        /// Initializes a new instance of the <see cref="Inventory"/> class.
        /// </summary>
        /// <param name="contents">The contents.</param>
        public Inventory(IEnumerable<Item> contents)
        {
            if (contents != null)
            {
                actualContents = new List<Item>(contents);
            }
            else
            {
                actualContents = new List<Item>();
            }
            Contents = new ReadOnlyCollection<Item>(actualContents);
            Capacity = DefaultCapacity > actualContents.Count ? DefaultCapacity : actualContents.Count;
        }

        private List<Item> actualContents;
        /// <summary>
        /// Gets the contents of the inventory.
        /// </summary>
        /// <value>The contents.</value>
        public ReadOnlyCollection<Item> Contents { get; private set; }

        private int capacity = DefaultCapacity;
        private const int DefaultCapacity = 50;
        /// <summary>
        /// Gets or sets the capacity of the inventory.
        /// </summary>
        /// <value>The capacity.</value>
        public int Capacity
        {
            get { return capacity; }
            set
            {
                Debug.Assert(capacity >= actualContents.Count, "capacity >= actualContents.Count");
                if (capacity < actualContents.Count)
                {
                    throw new ArgumentException("Capacity is less than the current contents.", "value");
                }
                capacity = value;
            }
        }

        /// <summary>
        /// Adds an item to the inventory.
        /// </summary>
        /// <param name="item">The item.</param>
        public void AddItem(Item item)
        {
            Debug.Assert(item != null, "item != null");
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            Debug.Assert(actualContents != null, "actualContents != null");
            if (actualContents == null)
            {
                actualContents = new List<Item>();
                Contents = new ReadOnlyCollection<Item>(actualContents);
            }

            Debug.Assert(actualContents.Count < Capacity, "actualContents.Count < Capacity");
            if (actualContents.Count >= Capacity)
            {
                throw new System.InvalidOperationException("Inventory at maximum capacity.");
            }
            actualContents.Add(item);
        }
    }
}
